<template>
  <div ref="wrapper" style="width: 100%; height: 100%">
    <div
      :id="props.id"
      :ref="props.id"
      style="width: 100%; height: 100%"
      :class="props?.className"
    ></div>
  </div>
</template>

<script setup lang="ts" name="ECharts">
import { ref, onMounted, onBeforeUnmount, watch, markRaw, nextTick } from "vue";
import { EChartsType, ECElementEvent } from "echarts/core";
import echarts, { ECOption } from "./config";
import { useDebounceFn } from "@vueuse/core";
import ElementResizeDetectorMaker from "element-resize-detector";

const erd = ElementResizeDetectorMaker();

interface Props {
  option: ECOption;
  renderer?: "canvas" | "svg";
  resize?: boolean;
  theme?: Object | string;
  width?: number | string;
  height?: number | string;
  className?: string;
  id?: "chartRef";
  showAllLabel?: false;
  onClick?: (event: ECElementEvent) => any;
}

const props = withDefaults(defineProps<Props>(), {
  renderer: "canvas",
  resize: true,
  id: "chartRef",
  showAllLabel: false,
});

// console.log("chartRef", props.id);

const chartRef = ref<HTMLDivElement | HTMLCanvasElement>();
const chartInstance = ref<EChartsType>();

const datazoomStart = ref(null);
const datazoomEnd = ref(null);
const draw = () => {
  if (chartInstance.value) {
    chartInstance.value.setOption(props.option, { notMerge: true });

    props.showAllLabel && adjustLabelRotation();
    // 添加 datazoom 事件监听器
    chartInstance.value.on("datazoom", function (event: any) {
      // 输出缩放的详细信息
      datazoomStart.value =
        event.batch && event.batch.length ? event?.batch[0]?.start : 0;
      datazoomEnd.value =
        event.batch && event.batch.length ? event?.batch[0]?.end : 100;
      // console.log("start", event.batch[0].start); // 缩放开始的数据索引
      // console.log("end", event.batch[0].end); // 缩放结束的数据索引
      // 可以根据需要进行更多操作
    });
  }
};

watch(props, () => {
  draw();
});

const handleClick = (event: ECElementEvent) =>
  props.onClick && props.onClick(event);

const init = () => {
  if (!document.getElementById(props.id)) return;
  chartInstance.value = echarts?.getInstanceByDom(
    document.getElementById(props.id)
  );

  if (!chartInstance.value) {
    chartInstance.value = markRaw(
      echarts.init(document.getElementById(props.id), props.theme, {
        renderer: props.renderer,
      })
    );
    chartInstance.value.on("click", handleClick);
    draw();
  }
};

const resize = () => {
  // console.log("chartInstance.value", chartInstance.value);
  if (chartInstance.value && props.resize) {
    chartInstance.value?.resize({ animation: { duration: 300 } });
  }
};

const debouncedResize = useDebounceFn(resize, 300, { maxWait: 800 });

const wrapper = ref(null);
onMounted(() => {
  nextTick(() => init());
  nextTick(() => {
    erd.listenTo(wrapper.value, (ele) => {
      //...元素尺寸变化调用其他方法
      resize();
    });
  });
  // 监听窗口大小变化
  window.addEventListener("resize", () => {
    props.showAllLabel && adjustLabelRotation();
    debouncedResize(); // 调整图表大小
    // adjustLabelRotation(); // 动态调整标签旋转角度
  });
});

// 动态调整 X 轴标签的旋转角度
function adjustLabelRotation() {
  const chartDom = document.getElementById(props.id);
  // console.log("chartDom", chartDom);
  const chartWidth = chartDom?.offsetWidth || 0; // 获取图表容器的宽度
  const labelCount =
    (props.option?.xAxis[0]?.data?.length ||
      props.option?.xAxis?.data?.length) ??
    0; // 获取 X 轴标签的数量
  const avgLabelWidth = 110; // 假设每个标签平均宽度为 100px

  // console.log("chartDom", chartWidth / labelCount, avgLabelWidth);

  // 如果容器宽度不足以容纳所有标签，则旋转标签
  if (avgLabelWidth - chartWidth / labelCount > 40) {
    chartInstance.value?.setOption({
      xAxis: {
        axisLabel: {
          rotate: 90, // 设置旋转角度为 45 度
        },
      },
    });
  } else if (chartWidth / labelCount < avgLabelWidth) {
    chartInstance.value?.setOption({
      xAxis: {
        axisLabel: {
          rotate: 45, // 设置旋转角度为 45 度
        },
      },
    });
  } else {
    chartInstance.value?.setOption({
      xAxis: {
        axisLabel: {
          rotate: 0, // 恢复为横向展示
        },
      },
    });
  }
}

onBeforeUnmount(() => {
  chartInstance.value?.dispose();
  window.removeEventListener("resize", debouncedResize);
});

defineExpose({
  getInstance: () => chartInstance.value,
  resize,
  draw,
  datazoomStart,
  datazoomEnd,
  chartInstance,
});
</script>
